/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge<T extends { [key: string]: any }>(target: T, source: T | any[]): T {
  if (typeof target !== 'object') {
    target = {} as T
  }
  if (Array.isArray(source)) {
    return source.slice() as unknown as T
  }
  const result = { ...target } as T
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property]
    if (typeof sourceProperty === 'object') {
      (result as any)[property] = objectMerge((result as any)[property], sourceProperty)
    } else {
      (result as any)[property] = sourceProperty
    }
  })
  return result
} 